﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Data;
using System.Configuration;

using ElCharro01.Helpers;
using ElCharro01.Models;
namespace ElCharro01.Areas.User.Controllers
{
    public class OrderController : Controller
    {
        private Entities db = new Entities();
        //
        // GET: /User/Order/

        public ActionResult Index()
        {
            //prendo i dati dalla session
            int userId = (int)Session["UserId"];

            Customer Customer = (Customer)db.UserSet.Single(u => u.ID == userId);

            return View(Customer.Order.OrderBy(o => o.DataOrdine).ToList());
        }

        public ActionResult Details(int id)
        {
            Order Order = db.OrderSet.Single(o => o.Id == id);
            return View(Order);
        }

        //prendendo i dati dal carrello creo un ordine
        public ActionResult Create(int locationId, string paymentType, bool bonusUsed)
        {
            // prendo i dati dalla session
            int cartId = (int)Session["cartId"];
            int userId = (int)Session["UserId"];
            decimal TotaleOrdine = 0;

            //recupero il cart e l'user dal db
            Cart Cart = db.CartSet.Single(c => c.Id == cartId);
            Customer Customer = (Customer)db.UserSet.Single(u => u.ID == userId);

            //creo l'order
            Order Order = new Order();
            Order.Customer = Customer;
            Order.ConfermaPagamento = false;
            Order.ConfermaSpedizione = false;
            Order.DataOrdine = DateTime.Now;
            Order.TipoDiPagamento = paymentType;
            if (paymentType == "Contrassegno")
            {
                Order.ConfermaPagamento = true;
            }

            Order.Totale = 0;   //il costo totale lo agiornerò una volta creati i CartDetail
            Order.Location = db.LocationSet.Single(l => l.Id == locationId);
            Order.BonusUsed = bonusUsed;
            db.OrderSet.AddObject(Order);
            db.SaveChanges();

            //recupero i CartDetail 
            List<CartDetail> CartDetailList = Cart.CartDetail.ToList();

            //creo un DetailOrder per ogni CartDetail
            foreach (CartDetail cartDetail in CartDetailList)
            {
                DetailOrder detailOrder = new DetailOrder();
                detailOrder.Quantita = cartDetail.Quantita;
                detailOrder.Totale = cartDetail.Variant.PrezzoUnitario * cartDetail.Quantita;
                detailOrder.Order = Order;
                detailOrder.Variant = cartDetail.Variant;
                db.DetailOrderSet.AddObject(detailOrder);
                db.SaveChanges();

                //calcolo il totale dell'ordine sommando i totali parziali dei DetailOrder
                TotaleOrdine = TotaleOrdine + detailOrder.Totale;
            }

            //aggiungo le spese di spedizione
            TotaleOrdine = TotaleOrdine + Convert.ToDecimal(ConfigurationManager.AppSettings["SpeseSpedizione"]);
            //se necessario aggingo le spese del contrassegno
            if (paymentType == "Contrassegno")
                TotaleOrdine = TotaleOrdine + Convert.ToDecimal(ConfigurationManager.AppSettings["CostoContrassegno"]);

            //se è stato utilizzato il bonus al costo totale appena calcolato verrà sottratto il bonus
            if (bonusUsed)
            {
                Order.TotalePreBonus = TotaleOrdine + Convert.ToDecimal(ConfigurationManager.AppSettings["SpeseSpedizione"]);

                //se il bonus è minore del prezzo degli articoli ordinati azzero il bonus e diminuisco il totale da pagare
                if (Customer.Bonus < TotaleOrdine)
                {
                    TotaleOrdine = TotaleOrdine - (decimal)Customer.Bonus + Convert.ToDecimal(ConfigurationManager.AppSettings["SpeseSpedizione"]);
                    Customer.Bonus = 0;
                }
                //se il bonus è maggiore del prezzo degli articoli ordinati aggiorno il bonus ed azzero il totale da pagare
                else
                {
                    TotaleOrdine = Convert.ToDecimal(ConfigurationManager.AppSettings["SpeseSpedizione"]);
                    Customer.Bonus = Customer.Bonus - TotaleOrdine;
                }

                db.ObjectStateManager.ChangeObjectState(Customer, EntityState.Unchanged);
                db.UserSet.Attach(Customer);
                db.ObjectStateManager.ChangeObjectState(Customer, EntityState.Modified);
                db.SaveChanges();

            }

            //aggiorno il costo totale
            Order.Totale = TotaleOrdine;
            db.ObjectStateManager.ChangeObjectState(Order, EntityState.Unchanged);
            db.OrderSet.Attach(Order);
            db.ObjectStateManager.ChangeObjectState(Order, EntityState.Modified);

            //cancello il carrello dato che ormai è diventato un order
            db.CartSet.DeleteObject(Cart);
            db.SaveChanges();

            //reinizializzo la variabile cart della session
            Session["cartId"] = 0;

            List<DetailOrder> DetailOrderList = Order.Detail.ToList();

            //aggiorno le quantità disponibili nel magazzino
            UpdateInstockQuantity(Order.Id);

            //notifico l'ordine agli admin attraverso una mail
            bool succeded;
            try
            {
                succeded = SendAdminOrderConfirmationMail(Order.Id) && SendUserOrderConfirmationMail(Order.Id);

            }
            catch (Exception ex)
            {
                succeded = false;
            }

            if (Order.TipoDiPagamento == "Paypal")
            {
                return RedirectToAction("PaypalCheckout", "Paypal", new { orderId = Order.Id });
            }
            else
                return RedirectToAction("OrderSucceded", "Order", new { });
        }


        public bool SendAdminOrderConfirmationMail(int orderId)
        {
            Order Order = db.OrderSet.Single(o => o.Id == orderId);
            List<DetailOrder> DetailOrderList = Order.Detail.ToList();
            List<string> OrderedVariants = new List<String>();

            /*aggiungo in OrderedVariants una stringa per ogni variante ordinato contenente il nome del prodotto
             * correlato a quella variante e la quantità ordinata*/
            //aggiorno le quantità disponibili nel magazzino
            foreach (DetailOrder detailOrder in DetailOrderList)
            {
                OrderedVariants.Add("<br />" + "Nome Prodotto:" +
                    detailOrder.Variant.Product.Nome + "<br />" +
                    "Colore :" + detailOrder.Variant.Colore + "<br />" +
                    "Taglia :" + detailOrder.Variant.Taglia + "<br />" +
                    "Quantità :" + detailOrder.Quantita + "<br />");
            }

            string ConcatenatedOrderdVariants = "";
            foreach (string prodottoOrdinato in OrderedVariants)
            {
                ConcatenatedOrderdVariants = ConcatenatedOrderdVariants + prodottoOrdinato;
            }

            try
            {
                String message = "<h3>E' stato effettuato, in data " + DateTime.Now + " il seguente ordine: " + "</h3><br />"
                                + ConcatenatedOrderdVariants + "<br />" +
                               "<h3>Dati Relativi Al Cliente: </h3>" + "<br />"
                               + "Nome: " + Order.Customer.Nome + "<br />"
                               + "Cognome: " + Order.Customer.Cognome + "<br />"
                               + "Indirizzo E-Mail: " + Order.Customer.Email + "<br />"
                               + "Numero Cellulare: " + Order.Customer.Cellulare + "<br />"
                               + "<h3>Dati Relativi Alla Spedizione:</h3>" + "<br />"
                               + "Nazione: " + Order.Location.Nazione + "<br />"
                               + "Città: " + Order.Location.Citta + "<br />"
                               + "Cap: " + Order.Location.CodicePostale + "<br />"
                               + "Indirizzo: " + Order.Location.Indirizzo;

                if (Order.BonusUsed)
                {

                    decimal bonudUsed = (decimal)Order.TotalePreBonus - Order.Totale + Convert.ToDecimal(ConfigurationManager.AppSettings["SpeseSpedizione"]);
                    message = message + "<h3>Dati Relativi Al Pagamento </h3>" + "<br />"
                                      + "Tipo di pagamento scelto dal cliente: " + Order.TipoDiPagamento + "<br />"
                                      + "E' stato utilizzato un bonus pari a : " + bonudUsed + "<br />"
                                      + "Il totale da pagare prima dell'utilizzo del bonus era di : " + Order.TotalePreBonus + "<br />"
                                      + "Il totale dovuto a seguito del pagamento del bonus è di : " + Order.Totale;
                }
                else
                    message = message + "<h3>Dati Relativi Al Pagamento </h3>" + "<br />"
                                      + "Tipo di pagamento scelto dal cliente: " + Order.TipoDiPagamento + "<br />"
                                      + "Il totale dovuto a è di : €" + Order.Totale;
                /* Send Mail */
                MailHelper.SendMailMessage("zen_master@hotmail.it",
                                           "",
                                           "javierfarinos@yahoo.it",
                                           "Nuovo Ordine Effettuato",
                                           message,
                                          ConfigurationManager.AppSettings["Email"]);
            }

            catch (Exception ex)
            {
                return false;
            }

            return true;

        }

        public bool SendUserOrderConfirmationMail(int orderId)
        {
            Order Order = db.OrderSet.Single(o => o.Id == orderId);
            List<DetailOrder> DetailOrderList = Order.Detail.ToList();
            List<string> OrderedVariants = new List<String>();

            /*aggiungo in OrderedVariants una stringa per ogni variante ordinato contenente il nome del prodotto
             * correlato a quella variante e la quantità ordinata*/
            //aggiorno le quantità disponibili nel magazzino
            foreach (DetailOrder detailOrder in DetailOrderList)
            {
                OrderedVariants.Add("<br />" + "Nome Prodotto:" +
                    detailOrder.Variant.Product.Nome + "<br />" +
                    "Colore :" + detailOrder.Variant.Colore + "<br />" +
                    "Taglia :" + detailOrder.Variant.Taglia + "<br />" +
                    "Quantità :" + detailOrder.Quantita + "<br />" +
                    "Prezzo Unitario Prodotto" + detailOrder.Variant.PrezzoUnitario + " €");
            }

            string ConcatenatedOrderdVariants = "";
            foreach (string prodottoOrdinato in OrderedVariants)
            {
                ConcatenatedOrderdVariants = ConcatenatedOrderdVariants + prodottoOrdinato;
            }

            try
            {
                String message = "<h3>Hai effettuato un ordine su ElCharro in data " + DateTime.Now + " per i seguenti articoli: </h3><br />"
                                 + ConcatenatedOrderdVariants + "<br />";


                if (Order.BonusUsed)
                {

                    decimal bonudUsed = (decimal)Order.TotalePreBonus - Order.Totale + Convert.ToDecimal(ConfigurationManager.AppSettings["SpeseSpedizione"]);
                    message = message + "<h3>Dati Relativi Al Pagamento </h3>" + "<br />"
                                      + "Tipo di pagamento da te scelto è: " + Order.TipoDiPagamento + "<br />"
                                      + "Hai utilizzato un bonus pari a : " + bonudUsed + "<br />"
                                      + "Il totale dovuto comprensivo di spese di spedizione prima dell'utilizzo del bonus era di : " + Order.TotalePreBonus + "<br />"
                                      + "Il totale dovuto comprensivo di spese di spedizione a seguito dell'utilizzo del bonus è di : " + Order.Totale
                                      + " (spese di spedizione " + Convert.ToDouble(ConfigurationManager.AppSettings["SpeseSpedizione"]) + " €" + "<br />";
                }
                else
                {
                    message = message + "<h3>Dati Relativi Al Pagamento </h3>" + "<br />"
                                      + "Tipo di pagamento scelto dal cliente: " + Order.TipoDiPagamento + "<br />"
                                      + "Il totale dovuto, comprensivo delle spese di spedizione è di: " + Order.Totale
                                      + " (spese di spedizione " + Convert.ToDouble(ConfigurationManager.AppSettings["SpeseSpedizione"]) + " €)" + "<br />";
                }
                // aggiungo i dati necessari al cliente per effettuare il pagamento
                if (Order.TipoDiPagamento == "Vaglia Postale")
                    message = message + "<h3>Coordinate Necessarie Per Effettuare Il Vaglia Postale </h3>" + "<br />"
                                      + ConfigurationManager.AppSettings["VagliaPostale"] + "<br />";
                else
                    if (Order.TipoDiPagamento == "Ricarica PostePay")
                        message = message + "<h3>Coordinate Necessarie Per Effettuare La Ricarica PostePay </h3>" + "<br />"
                                     + ConfigurationManager.AppSettings["PostePay"] + "<br />";

                /* Send Mail */
                MailHelper.SendMailMessage(Order.Customer.Email,
                                           "",
                                           "",
                                           "Conferma Ordine ElCharro",
                                           message,
                                          ConfigurationManager.AppSettings["Email"]);
            }

            catch (Exception ex)
            {
                return false;
            }

            return true;

        }

        public void UpdateInstockQuantity(int id)
        {
            Order Order = db.OrderSet.Single(o => o.Id == id);
            List<DetailOrder> DetailOrderList = Order.Detail.ToList();

            //aggiorno le quantità disponibili nel magazzino
            foreach (DetailOrder detailOrder in DetailOrderList)
            {
                Variant Variant = new Variant();
                Variant = detailOrder.Variant;
                Variant.InStock = Variant.InStock - detailOrder.Quantita;
                db.ObjectStateManager.ChangeObjectState(Order, EntityState.Unchanged);
                db.OrderSet.Attach(Order);
                db.ObjectStateManager.ChangeObjectState(Order, EntityState.Modified);
                db.SaveChanges();
            }
        }

        public ActionResult OrderSucceded()
        {
            return View();
        }

        public ActionResult PayPalComplete(int id)
        {
            Order order = db.OrderSet.Single(o => o.Id == id);
            ViewBag.CustomerName = order.Customer.Nome;
            ViewBag.CustomerSurname = order.Customer.Cognome;
            ViewBag.CustomerMail = order.Customer.Email;
            return View();
        }
    }
}
